linux input: TTP229触摸键盘驱动 | 您所在的位置:网站首页 › linux 键盘 驱动 › linux input: TTP229触摸键盘驱动 |
1. 前言
限于作者能力水平,本文可能存在的谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 背景门禁设备加入一款 TTP229 芯片,作为输入键盘,没有驱动代码提供,需为该设备编写Linux input驱动。设备相关原理图如下: 用两个 GPIO 模拟 I2C 的 SCL,SDO: static int ttp229_timing_init(struct ttp229_device *ttp229) { int result; if (!ttp229) return -EINVAL; result = ttp229_gpio_request(TTP229_SCL, "ttp229-scl"); if (result) goto scl_req_err; gpio_direction_output(TTP229_SCL, !SAMPLE_LEVEL); result = ttp229_gpio_request(TTP229_SDO, "ttp229-sdo"); if (result) goto sdo_req_err; gpio_direction_output(TTP229_SDO, !SAMPLE_LEVEL); ttp229->state = 0xFFFF; return 0; sdo_req_err: gpio_free(TTP229_SCL); scl_req_err: return result; }注册设备到内核input子系统: static int ttp229_input_init(struct ttp229_device *ttp229) { struct input_dev *input_dev; int i, result; input_dev = input_allocate_device(); if (!input_dev) { result = -ENOMEM; dev_err(&ttp229->pdev->dev, "input_allocate_device error\n"); goto input_alloc_err; } input_dev->name = "ttp229-keypad"; input_dev->dev.parent = &ttp229->pdev->dev; for(i = 0; i evbit); ttp229->input_dev = input_dev; result = input_register_device(ttp229->input_dev); if (result) { dev_err(&ttp229->pdev->dev, "input_register_device error\n"); goto input_register_err; } /* 无中断信号,只能用 timer 或者 work 方式轮训输入 */ #if (SAMPLE_FACILITY == 0) setup_timer(&ttp229->input_timer, ttp229_input_timer_fn, (unsigned long)ttp229); mod_timer(&ttp229->input_timer, jiffies + msecs_to_jiffies(5)); #elif (SAMPLE_FACILITY == 1) INIT_DELAYED_WORK(&ttp229->input_work, ttp229_input_work); schedule_delayed_work(&ttp229->input_work, msecs_to_jiffies(5)); #endif return 0; input_register_err: input_free_device(ttp229->input_dev); input_alloc_err: return result; } 3.3 按键采样和上报 #if (SAMPLE_FACILITY == 0) static void ttp229_input_timer_fn(unsigned long data) { struct ttp229_device *ttp229 = (struct ttp229_device *)data; ttp229_key_report(ttp229, ttp229_sample()); mod_timer(&ttp229->input_timer, jiffies + msecs_to_jiffies(SAMPLE_PERIOD)); } #elif (SAMPLE_FACILITY == 1) static void ttp229_input_work(struct work_struct *work) { struct delayed_work *input_work = to_delayed_work(work); struct ttp229_device *ttp229 = container_of(input_work, struct ttp229_device, input_work); ttp229_key_report(ttp229, ttp229_sample()); schedule_delayed_work(&ttp229->input_work, msecs_to_jiffies(SAMPLE_PERIOD)); } #endif 3.3.1 按键采样 static const struct ttp229_key_map { __u16 data; unsigned int code; } key_hash_tb[] = { { 0xFDFD, KEY_1 }, { 0xFBFB, KEY_2 }, { 0xF7F7, KEY_3 }, { 0xEFEF, KEY_4 }, { 0xDFDF, KEY_5 }, { 0xBFBF, KEY_6 }, { 0x7F7F, KEY_7 }, { 0xFEFF, KEY_8 }, #if 0 /* TODO: remain 8 keys */ { 0xFFFF, KEY_9 }, { 0xFFFF, KEY_0 }, { 0xFFFF, KEY_F1 }, { 0xFFFF, KEY_F2 }, { 0xFFFF, KEY_F3 }, { 0xFFFF, KEY_F4 }, { 0xFFFF, KEY_F5 }, { 0xFFFF, KEY_F6 }, #endif }; static unsigned int ttp229_key_hash(__u16 data) { int i; for (i = 0; i gpio_set_value(TTP229_SCL, SAMPLE_LEVEL); data |= (gpio_get_value(TTP229_SDO) |
CopyRight 2018-2019 实验室设备网 版权所有 |